#include "chess.h"
#include "ui_chess.h"
#include<QPainter>
#include<QMouseEvent>
#include<math.h>
#include<QFont>
chess::chess(QWidget *parent) :

    QMainWindow(parent),
    ui(new Ui::chess)
{
    ui->setupUi(this);
    this->setGeometry(680,240,1200,1200);
}

chess::~chess()
{
    delete ui;
}
int chess::arr[4][4]={-1,-1,-1,-1,0,0,0,0,0,0,0,0,1,1,1,1};//代表棋子
bool chess::bugkiller=true;//初始化为true以进行第一次左键选择棋子
int chess::sum[4]={0,0,0,0};//用于储存行或列中无子点的个数，用于吃子判断，仅某行或列有三个子时才可能出现吃子，即sum为1时
void chess::paintEvent(QPaintEvent *event)
{
    //画棋盘
    QPainter painter(this);
    painter.setPen(Qt::black);//画笔颜色
    painter.setBrush(Qt::white);//填充颜色,暂时用不到
    painter.drawRect(75,75,1050,1050);//框线大小
    for(int i=1;i<3;i++)
    {
        painter.drawLine(75,75+350*i,1125,75+350*i);//画横线
        painter.drawLine(75+350*i,75,75+350*i,1125);//画竖线

    }
    //初始化棋子
    QPixmap picbl;//黑子图片
    QPixmap picblchoose;//选择状态下黑子图片
    QPixmap picwh;//白子图片
    QPixmap picwhchoose;//选择状态下白子图片
    picwh.load(":/new/prefix1/白子.png");
    picwhchoose.load(":/new/prefix1/白子选择状态.png");
    picbl.load (":/new/prefix1/黑子.png");
    picblchoose.load(":/new/prefix1/黑子选择状态.png");
    for(int i=0;i<=3;i++)
    {
        for(int j=0;j<=3;j++)
        {
          if(arr[i][j]==-1)
              painter.drawPixmap(0+350*j,0+350*i,150,150,picwh);//画白子
          if(arr[i][j]==-2)
              painter.drawPixmap(0+350*j,0+350*i,150,150,picwhchoose);//画选择状态下白子
          if(arr[i][j]==1)
              painter.drawPixmap(0+350*j,0+350*i,150,150,picbl);//画黑子
          if(arr[i][j]==2)
              painter.drawPixmap(0+350*j,0+350*i,150,150,picblchoose);//画选择状态下黑子
        }
    }
    QFont dis("STSong",50);//显示胜利的字体和大小坐标
    painter.setFont(dis);
    painter.setPen(Qt::red);
    painter.setBrush(Qt::red);
    painter.drawText(400,600,display);
}
void chess:: mousePressEvent(QMouseEvent *event)//实现棋子移动
{
    if(event->button()==Qt::LeftButton&&bugkiller)//判定
    {
        l=event->pos();//第一次左键所点击位置相对窗口坐标
        l_x=event->x();//横坐标
        l_y=event->y();//纵坐标
        if(arr[int(l_y/350)][int(l_x/350)]==pow(con,count))//黑子先，开始为-1^2,对应为黑子，然后白，再然后黑，并且这个数与数组中相应子的代表数字相同，乘二即为选择状态
           {
            arr[int(l_y/350)][int(l_x/350)]*=2;
            count++;//实现回合判断
            update();//更新画图
            bugkiller=false;//使判定为误，不能连续左键操作，从而解决bug
        }

    }
    if(event->button()==Qt::LeftButton)
    {
        r=event->pos();//第二次左键
        r_x=event->x();
        r_y=event->y();
        if(arr[r_y/350][r_x/350]==0)//判断右键所点处无子
        {
            if((abs(r_x/350-l_x/350)==1&&r_y/350==l_y/350)||(abs(r_y/350-l_y/350)==1&&r_x/350==l_x/350))//第二次左键所点处与第一次左键选择的点十字相邻
           {
                arr[l_y/350][l_x/350]=0;//第一次左键选择的子消失
                arr[r_y/350][r_x/350]=pow(con,count-1);//第二次左键点处出现消失的子，实现移动
                killpiece(pow(con,count));//吃子，黑子走时能吃白子，黑子不能自杀反之亦然
                update();//更新
                if(determine()==-1)//判断结果
                    display="黑子胜利";
                if(determine()==1)
                    display="白子胜利";
                bugkiller=true;//移动后才能再次选择棋子
            }
        }
    }
}
void chess::killpiece(int type)
{
    //判断列吃子情况
   {
        //重新置零
            for(int i=0;i<=3;i++)
                   sum[i]=0;//判断吃子要置零，否则会存储上次信息，导致吃子出错

            for(int j=0;j<=3;j++)
              for(int i=0;i<=3;i++)
              {
                if(arr[i][j]==0)
                    sum[j]++;//统计第j列空子数
              }
            for(int j=0;j<=3;j++)
              if(sum[j]==1)//可能产生吃子情况
            {
                if(arr[0][j]==-1&&arr[1][j]==1&&arr[2][j]==1&&arr[0][j]==type)
                    arr[0][j]=0;
                if(arr[1][j]==-1&&arr[2][j]==1&&arr[3][j]==1&&arr[1][j]==type)
                    arr[1][j]=0;
                if(arr[3][j]==-1&&arr[2][j]==1&&arr[1][j]==1&&arr[3][j]==type)
                    arr[3][j]=0;
                if(arr[2][j]==-1&&arr[1][j]==1&&arr[0][j]==1&&arr[2][j]==type)//吃白子
                    arr[2][j]=0;
                if(arr[0][j]==1&&arr[1][j]==-1&&arr[2][j]==-1&&arr[0][j]==type)
                    arr[0][j]=0;
                if(arr[1][j]==1&&arr[2][j]==-1&&arr[3][j]==-1&&arr[1][j]==type)
                    arr[1][j]=0;
                if(arr[3][j]==1&&arr[2][j]==-1&&arr[1][j]==-1&&arr[3][j]==type)
                    arr[3][j]=0;
                if(arr[2][j]==1&&arr[1][j]==-1&&arr[0][j]==-1&&arr[2][j]==type)//吃黑子
                    arr[2][j]=0;



            }
    }
    //判断行吃子情况
    {
        //重新置零
        for(int i=0;i<=3;i++)
               sum[i]=0;//同上
        for(int i=0;i<=3;i++)
            for(int j=0;j<=3;j++)
            {
                if(arr[i][j]==0)
                    sum[i]++;//统计第i行空子数
            }
        for(int i=0;i<=3;i++)
            if(sum[i]==1)//同上
            {
                if(arr[i][0]==-1&&arr[i][1]==1&&arr[i][2]==1&&arr[i][0]==type)
                    arr[i][0]=0;
                if(arr[i][1]==-1&&arr[i][2]==1&&arr[i][3]==1&&arr[i][1]==type)
                    arr[i][1]=0;
                if(arr[i][3]==-1&&arr[i][2]==1&&arr[i][1]==1&&arr[i][3]==type)
                    arr[i][3]=0;
                if(arr[i][2]==-1&&arr[i][1]==1&&arr[i][0]==1&&arr[i][2]==type)//吃白子
                    arr[i][2]=0;
                if(arr[i][0]==1&&arr[i][1]==-1&&arr[i][2]==-1&&arr[i][0]==type)
                    arr[i][0]=0;
                if(arr[i][1]==1&&arr[i][2]==-1&&arr[i][3]==-1&&arr[i][1]==type)
                    arr[i][1]=0;
                if(arr[i][3]==1&&arr[i][2]==-1&&arr[i][1]==-1&&arr[i][3]==type)
                    arr[i][3]=0;
                if(arr[i][2]==1&&arr[i][1]==-1&&arr[i][0]==-1&&arr[i][2]==type)//吃黑子
                    arr[i][2]=0;
            }

    }


}
int chess::determine()
{
    //剩一个棋子则输
    {//判断白子是否仅剩一个
        sumofpiece=0;
        for(int i=0;i<=3;i++)
            for(int j=0;j<=3;j++)
            {
                if(arr[i][j]==-1)
                    sumofpiece++;
            }
        if(sumofpiece==1)
            return -1;
    }
    {//判断黑子是否仅剩一个
        sumofpiece=0;
        for(int i=0;i<=3;i++)
            for(int j=0;j<=3;j++)
            {
                if(arr[i][j]==1)
                    sumofpiece++;
            }
        if(sumofpiece==1)
            return 1;
    }
    //无法移动一方输
   {//判断白子是否会无法移动
        sumofpiece=0;
        for(int i=0;i<=3;i++)
            for(int j=0;j<=3;j++)
            {
                if(arr[i][j]==-1)
                   {
                    if(i-1>=0)
                        if(arr[i-1][j]==0)
                            sumofpiece++;
                    if(i+1<=3)
                        if(arr[i+1][j]==0)
                            sumofpiece++;
                    if(j-1>=0)
                        if(arr[i][j-1]==0)
                            sumofpiece++;
                    if(j+1<=3)
                        if(arr[i][j+1]==0)
                            sumofpiece++;
                }
            }
        if(sumofpiece==0)
            return -1;

    }
   {//判断黑子是否会无法移动
        sumofpiece=0;
        for(int i=0;i<=3;i++)
            for(int j=0;j<=3;j++)
            {
                if(arr[i][j]==1)
                   {
                    if(i-1>=0)
                        if(arr[i-1][j]==0)
                            sumofpiece++;
                    if(i+1<=3)
                        if(arr[i+1][j]==0)
                            sumofpiece++;
                    if(j-1>=0)
                        if(arr[i][j-1]==0)
                            sumofpiece++;
                    if(j+1<=3)
                        if(arr[i][j+1]==0)
                            sumofpiece++;
                }
            }
        if(sumofpiece==0)
            return 1;

    }
}




